package com.aldobucchi.x.flash.events
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	

/**
 *  
 * 
 *  @eventType com.aldobucchi.x.flash.events.EventHookEvent
 */
[Event(name="fire", type="com.aldobucchi.x.flash.events.EventHookEvent")]


	/**
	 * 
	 * This class is useful when you want to declare an inline event handler using MXML
	 * to an IEventDispatcher that is not accessible through MXML
	 * 
	 * <events:EventHook dispatcher="{Application.application.systemManager}" eventType="resize" fire="trace('the app has resized!')"/>
	 * 
	 *  You can access the original event by inspecting the "originalEvent" property of the dispatched EventHookEvent
	 * 
	 * @author aldo.bucchi@gmail.com
	 * 
	 */
	public class EventHook extends EventDispatcher
	{
		
		//////////// dispatcher ////////////
		
		private var _dispatcher:IEventDispatcher = null;
		/**
		 * 
		 * @param v
		 * 
		 */		
		public function set dispatcher( v:IEventDispatcher ):void
		{
			if ( v == _dispatcher ) // dismiss
				return;
			
			if ( !hotSwap && dispatcher!=null ) // no hot swapping
				return;	
			
			remove();
			_dispatcher = v;
			add();
		}
		
		public function get dispatcher():IEventDispatcher
		{
			return _dispatcher;
		}

		/////////// eventType //////////////

		private var _eventType:String = null;

		public function set eventType( v:String ):void
		{
			if ( v == _eventType ) // dismiss
				return;
				
			if ( !hotSwap && eventType!=null ) // no hot swapping
				return;					
				
			remove();
			_eventType = v;
			add();
		}
		
		public function get eventType():String
		{
			return _eventType;
		}
		
		//////////// hot swap ////////////
		
		/**
		* If set to false, the target and the type can only be set once
		*/		
		public var hotSwap:Boolean = true;
		
		
		
		////////// private methods ///////////

		private function remove():void
		{
			if ( _dispatcher != null && _eventType != null ) // lets remove the previous event listener
				_dispatcher.removeEventListener( _eventType , handleEvent );
		}
		private function add():void
		{
			if ( _dispatcher != null && _eventType != null )
				_dispatcher.addEventListener( _eventType, handleEvent );
		}


		private function handleEvent( event:Event ):void
		{
			dispatchEvent( new EventHookEvent( EventHookEvent.FIRE, false, false, event ) );	
		}
			
		
	}
	
}